package com.glp.work.flow.client;

import com.glp.common.enums.ReturnEnum;
import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.request.DeleteRuningOrderRequest;
import com.glp.work.flow.request.MessageEventReceivedRequest;
import com.glp.work.flow.request.ProcessInitiateRequest;
import com.glp.work.flow.response.OrderHisInfoResponse;
import com.glp.work.flow.response.OrderStatusResponse;
import com.glp.work.flow.response.ProcessInitiateResponse;
import feign.hystrix.FallbackFactory;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.util.List;


/**
 * 外部系统发起工作流
 *
 * @author pengjia
 * @version 2020年3月9日 下午1:04:33
 */

@FeignClient(value = "${work.flow.feign.server.key:GLP-WORK-FLOW}", path = "/api/wf/process", fallbackFactory = WfProcessInitiateClient.ClientFallback.class)
public interface WfProcessInitiateClient {

    @ApiOperation(value = "发起工作流")
    @PostMapping(value = "/initiate", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public BaseResult<ProcessInitiateResponse> processInitate(@RequestBody ProcessInitiateRequest request);

    @ApiOperation(value = "发起工作流2.0")
    @PostMapping(value = "/initiateTwo", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public BaseResult<ProcessInitiateResponse> processInitateTwo(@RequestBody ProcessInitiateRequest request);

    @ApiOperation(value = "撤销工单(删除数据)")
    @PostMapping(value = "/deleteRuningOrder", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public BaseResult<ProcessInitiateResponse> deleteRuningOrder(@RequestBody DeleteRuningOrderRequest deleteRuningOrderRequest);

    @ApiOperation(value = "工单不通过")
    @PostMapping(value = "/auditFail")
    @ResponseBody
    public BaseResult<ProcessInitiateResponse> auditFailRuningOrder(@RequestBody DeleteRuningOrderRequest deleteRuningOrderRequest);

    @ApiOperation(value = "查询订单状态")
    @GetMapping(value = "/status/{processId}")
    @ResponseBody
    public BaseResult<OrderStatusResponse> queryOrderStatus(@PathVariable(value = "processId") String processId);

    @ApiOperation(value = "更新驳回工单状态为待审批")
    @GetMapping(value = "/updateStatus/{processId}")
    @ResponseBody
    public BaseResult<OrderStatusResponse> updateOrderStatus(@PathVariable(value = "processId") String processId);

    @ApiOperation(value = "已完成工单历史信息查询")
    @GetMapping(value = "/his/{orderId}")
    @ResponseBody
    public BaseResult<List<OrderHisInfoResponse>> queryOrderHistoryInfo(@PathVariable(value = "orderId") String orderId);

    @ApiOperation(value = "中间消息通知")
    @PostMapping(value = "/messageEventReceived")
    @ResponseBody
    public BaseResult<String> messageEventReceived(@RequestBody MessageEventReceivedRequest messageEventReceivedRequest);

    @Component
    @Slf4j
    public class ClientFallback implements FallbackFactory<WfProcessInitiateClient> {
        @Override
        public WfProcessInitiateClient create(Throwable cause) {
            return new WfProcessInitiateClient() {
                @Override
                public BaseResult<ProcessInitiateResponse> processInitate(ProcessInitiateRequest request) {
                    log.error("发起工作流失败（failBack）！appId:" + request.getAppId() + "procDefKey:" + request.getProcDefKey(), cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "发起工作流失败（failBack）！appId:" + request.getAppId() + "procDefKey:" + request.getProcDefKey());
                }

                @Override
                public BaseResult<ProcessInitiateResponse> processInitateTwo(ProcessInitiateRequest request) {
                    log.error("发起工作流失败（failBack）！appId:" + request.getAppId() + "procDefKey:" + request.getProcDefKey(), cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "发起工作流失败（failBack）！appId:" + request.getAppId() + "procDefKey:" + request.getProcDefKey());
                }

                @Override
                public BaseResult<ProcessInitiateResponse> deleteRuningOrder(DeleteRuningOrderRequest deleteRuningOrderRequest) {
                    log.error("撤销工单失败（failBack）！appId:" + deleteRuningOrderRequest.getAppId() + "processId:" + deleteRuningOrderRequest.getProcessId(), cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "撤销工单失败（failBack）！appId:" + deleteRuningOrderRequest.getAppId() + "processId:" + deleteRuningOrderRequest.getProcessId());
                }

                @Override
                public BaseResult<OrderStatusResponse> queryOrderStatus(String orderId) {
                    log.error("工单状态查询失败（failBack）！orderId:" + orderId, cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "工单状态查询失败（failBack）！orderId:" + orderId);
                }

                @Override
                public BaseResult<OrderStatusResponse> updateOrderStatus(String processId) {
                    log.error("被驳回工单状态更新失败（failBack）！orderId:" + processId, cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "被驳回工单状态更新失败（failBack）！processId:" + processId);
                }

                @Override
                public BaseResult<List<OrderHisInfoResponse>> queryOrderHistoryInfo(String orderId) {
                    log.error("已完成工单历史信息查询失败（failBack）！orderId:" + orderId, cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "已完成工单历史信息查询失败（failBack）！orderId:" + orderId);
                }

                @Override
                public BaseResult<String> messageEventReceived(
                        MessageEventReceivedRequest messageEventReceivedRequest) {
                    log.error("中间消息通知失败（failBack）！" + messageEventReceivedRequest, cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "中间消息通知失败（failBack）！" + messageEventReceivedRequest);
                }

                @Override
                public BaseResult<ProcessInitiateResponse> auditFailRuningOrder(
                        DeleteRuningOrderRequest deleteRuningOrderRequest) {
                    log.error("工单不通过失败（failBack）！appId:" + deleteRuningOrderRequest.getAppId() + "processId:" + deleteRuningOrderRequest.getProcessId(), cause);
                    return new BaseResult<>(ReturnEnum.ERROR.getCode(), "工单不通过失败（failBack）！appId:" + deleteRuningOrderRequest.getAppId() + "processId:" + deleteRuningOrderRequest.getProcessId());
                }

            };
        }
    }

}
